
#include "Socket.h";
#include "stdafx.h";

using namespace std;

#define DEBUGMODE false

int Sock::Init()
{
	if (DEBUGMODE) cout<<"Init connection..."<<endl;

	WSADATA wsaData = {0};
	WORD wVer = MAKEWORD(2,2);
		
	if( WSAStartup( wVer, &wsaData )== SOCKET_ERROR ) 
	{
		return -1;
	}
	if (DEBUGMODE) cout << "Init OK"<<endl;
	return 0;
}

char * Sock::ReceiveData()
{
	while(1)
	{
		char * buf;
		
		buf = _ReceiveData();
		if (buf != NULL) return &(*buf);
	}
}

char* Sock::_ReceiveData()
{
	char* buf = new char[SOCK_BUF_LEN];
	int iResult = recv(connSock, buf, SOCK_BUF_LEN, 0);
	if (iResult == SOCKET_ERROR || iResult == 0)
	{
		memset(buf, 0, SOCK_BUF_LEN);
		return NULL;
	}
	return buf;
	
}

char* Sock::ReceiveData(int n)
{
	char* buf = new char[n];
	for (int i=0;i<n;i++)
	{
		buf[i] = ReceiveData()[0];
	}
	return buf;
}

int Sock::SendData(char* data)
{
	int len = strlen(data);
	return send(connSock, data, len, 0);
}

void Sock::CloseSock(SOCKET so)
{
	closesocket(so);
	WSACleanup();
}

ServerSocket::ServerSocket(int port)
{
	int iResult;
	iResult = Init();
	if (iResult == -1)
	{
		cout << "Init error!"<<endl;
		WSACleanup();
	}

	if (DEBUGMODE) cout << "Creating socket..."<<endl;

	ListenSock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (ListenSock == INVALID_SOCKET)
	{
		cout << "Create Socket error!"<<endl;
		WSACleanup();
		return;
	}
	struct sockaddr_in local;
	memset(&local,0,sizeof(sockaddr_in));
	local.sin_family = AF_INET;
	local.sin_port = htons(port);
	local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	
	if (DEBUGMODE) cout << "Binding socket..."<<endl;

	iResult = bind(ListenSock,(sockaddr*)&local,sizeof(sockaddr));

	if (iResult == SOCKET_ERROR)
	{
		cout << "Bind error!"<<endl;
		CloseSock(ListenSock);
		return;
	}
	
	if (DEBUGMODE) cout << "Listening socket..."<<endl;

	iResult = listen(ListenSock,5);

	if (iResult == SOCKET_ERROR)
	{
		cout << "Listen error!"<<endl;
		CloseSock(ListenSock);
		return;
	}

	struct sockaddr_in clientAddr;
	memset(&clientAddr,0,sizeof(sockaddr_in));
	int addrlen = sizeof(sockaddr_in);
	
	if (DEBUGMODE) cout << "Accepting socket..."<<endl;

	connSock = accept(ListenSock,(sockaddr*)&clientAddr,&addrlen);

	
	if (DEBUGMODE) cout << "Socket accepted from "<< inet_ntoa(clientAddr.sin_addr) << endl;
}

ServerSocket::~ServerSocket()
{ 
	closesocket(ListenSock);
	closesocket(connSock);
	WSACleanup();
}

ClientSocket::ClientSocket(const char* ip, int port)
{
	int iResult;
	iResult = Init();
	if (iResult == -1)
	{
		cout << "Init error!"<<endl;
		WSACleanup();
	}

	connSock = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
	if (connSock == INVALID_SOCKET)
	{
		cout << "Create Socket error!"<<endl;
		WSACleanup();
		return;
	}

	sockaddr_in saServer = {0};
	saServer.sin_family = AF_INET;
	saServer.sin_port = htons(port);
	saServer.sin_addr.S_un.S_addr = inet_addr(ip);
	iResult = connect(connSock,(sockaddr*)&saServer,sizeof(sockaddr));
	if (iResult == SOCKET_ERROR)
	{
		closesocket(connSock);
		WSACleanup();
		return;
	}
}

ClientSocket::~ClientSocket()
{
    closesocket(connSock);
    WSACleanup();
}


